# include "../include/LogFile.h"

void ZDSJ::LogFile::output(const std::string& _log)
{
	std::string out = _log + "\r\n";
	size_t length = out.size();
	if (this->m_offset + length > this->m_max_size) {
		switch (this->m_stratgy)
		{
		case OverflowStratgy::overflow:
			this->overflow(out);
			break;
		case OverflowStratgy::truncation:
			this->truncation(out);
			break;
		case OverflowStratgy::strict:
			this->strict(out);
			break;
		default:
			break;
		}
		return;
	}
	this->m_offset = this->m_out->tellp();
	this->m_out->write(out.c_str(), out.size());
}

bool ZDSJ::LogFile::operator==(const LogFile& _other) const
{
	return *this->m_file_name == *_other.m_file_name;
}

ZDSJ::LogFile::LogFile(const std::string& _file_name, int _max_size, bool _loop, OverflowStratgy _stratgy) : 
	m_out(new std::ofstream()), m_file_name(new std::string(_file_name)), m_max_size(_max_size * KB), m_loop(_loop), m_stratgy(_stratgy)
{
	this->openFile();
}

ZDSJ::LogFile::~LogFile()
{
	delete this->m_file_name;
	this->m_out->flush();
	this->m_out->close();
	delete this->m_out;
}

void ZDSJ::LogFile::overflow(const std::string& _out)
{
	this->m_out->write(_out.c_str(), _out.size());
	this->dealOverFlow();
}

void ZDSJ::LogFile::truncation(const std::string& _out)
{
	size_t copy_size = this->m_max_size - this->m_offset;
	size_t surplus = _out.size() - copy_size;
	this->m_out->write(_out.c_str(), copy_size);
	this->dealOverFlow();
	this->m_out->write(_out.c_str() + copy_size, surplus);
	this->m_offset = this->m_out->tellp();
}

void ZDSJ::LogFile::strict(const std::string& _out)
{
	this->dealOverFlow();
	this->m_out->write(_out.c_str(), _out.size());
	this->m_offset = this->m_out->tellp();
}

void ZDSJ::LogFile::dealOverFlow()
{
	if (!this->m_loop) {
		this->m_out->close();
		std::string* tmp = new std::string(this->m_file_name->substr(0, this->m_file_name->size() - 5) + "1.txt");
		delete this->m_file_name;
		this->m_file_name = tmp;
		this->openFile();
	}
	else {
		this->m_out->flush();
	}
	this->m_out->seekp(0, std::ios::beg);
	this->m_offset = 0;
}

void ZDSJ::LogFile::openFile()
{
	this->m_out->open(*this->m_file_name, std::ios::binary | std::ios::out | std::ios::in);
	if (!this->m_out->is_open()) {
		std::ofstream* temp = new std::ofstream();
		temp->open(*this->m_file_name, std::ios::app);
		temp->close();
		delete temp;
		this->m_out->open(*this->m_file_name, std::ios::binary | std::ios::out | std::ios::in);
	}
	this->m_out->seekp(0, std::ios::end);
	this->m_offset = this->m_out->tellp();
}
